package com.margo.project.append.dao;

import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.stereotype.Repository;

import com.margo.project.append.model.Column;
import com.margo.project.append.model.MarColumnNameVO;

@Repository
public class MarColumnNameDAO {
	
	Logger logger=LoggerFactory.getLogger(this.getClass());
	@Autowired
	private JdbcTemplate jdbcTemplate;
	
	public List<MarColumnNameVO> queryMarColumnNameList(String tableName){
		StringBuilder sbSQL=new StringBuilder();
		sbSQL.append(" SELECT USER_TAB_COLUMNS.COLUMN_NAME,\n");
		sbSQL.append("        USER_TAB_COLUMNS.DATA_TYPE,\n");
		sbSQL.append("        USER_TAB_COLUMNS.DATA_LENGTH,\n");
		
		sbSQL.append("        USER_TAB_COLUMNS.DATA_PRECISION,\n");
		sbSQL.append("        USER_TAB_COLUMNS.DATA_SCALE,\n");
		sbSQL.append("        USER_TAB_COLUMNS.NULLABLE,\n");
		
		sbSQL.append("        USER_COL_COMMENTS.COMMENTS\n");
		sbSQL.append("   FROM USER_TAB_COLUMNS, USER_COL_COMMENTS\n");
		sbSQL.append("  WHERE USER_TAB_COLUMNS.COLUMN_NAME = USER_COL_COMMENTS.COLUMN_NAME\n");
		sbSQL.append("    AND USER_TAB_COLUMNS.TABLE_NAME = USER_COL_COMMENTS.TABLE_NAME\n");
		sbSQL.append("    AND USER_TAB_COLUMNS.TABLE_NAME = ? \n");
		sbSQL.append("  ORDER BY COLUMN_ID");
		Object[] param=new Object[1];
		param[0]=tableName;
		
//		RowMapper rowMapper = (RowMapper) Proxy.newProxyInstance(RowMapper.class.getClassLoader(), new Class<?>[] {RowMapper.class},new MarInvocationHandler<MarColumnNameVO.class>());
//		List<MarColumnNameVO> lstItem=jdbcTemplate.query(sbSQL.toString(), param,rowMapper);
		
		RowMapper<MarColumnNameVO> rowMapper=new RowMapper<MarColumnNameVO>() {
			@Override
			public MarColumnNameVO mapRow(ResultSet rs, int rowNum) throws SQLException {
				Class<MarColumnNameVO> cla=MarColumnNameVO.class;
				Map<String, String> columnMap=new HashMap<String, String>();
				Field[] fields=cla.getDeclaredFields();
				for(Field field:fields) {
					if(field.isAnnotationPresent(Column.class)) {
						for(Annotation anno : field.getDeclaredAnnotations()) {
							if(anno.annotationType().equals(Column.class)) {
								columnMap.put(((Column)anno).name(), field.getName());
							}
						}
					}
				}
				MarColumnNameVO marColumnNameVO=new MarColumnNameVO();
				Method method = null;
				for(String key:columnMap.keySet()) {
					String fieldName=columnMap.get(key);
					String firstLetter = fieldName.substring(0, 1).toUpperCase();
					String setter = "set" + firstLetter + fieldName.substring(1);
					try {
						//cla.getDeclaredMethod(setter) 如果没有参数不用写第二个参数如果有参数的
						method = cla.getDeclaredMethod(setter,String.class);
						method.invoke(marColumnNameVO,rs.getString(key));
					} catch (NoSuchMethodException e) {
						e.printStackTrace();
					} catch (SecurityException e) {
						e.printStackTrace();
					} catch (IllegalAccessException e) {
						e.printStackTrace();
					} catch (IllegalArgumentException e) {
						e.printStackTrace();
					} catch (InvocationTargetException e) {
						e.printStackTrace();
					}
				}
				return marColumnNameVO;
			}
		};
		List<MarColumnNameVO> lstItem=jdbcTemplate.query(sbSQL.toString(), param,rowMapper);
		for(MarColumnNameVO marColumnNameVO:lstItem) {
			logger.info(marColumnNameVO.toString());
		}
		//throw new RuntimeException();
		return lstItem;
	}
}
